home *** CD-ROM | disk | FTP | other *** search
/ BBS Toolkit / BBS Toolkit.iso / rbbs_pc / m2t050.zip / MSG2TXT.C next >
C/C++ Source or Header  |  1990-09-16  |  10KB  |  412 lines

  1. /* MSG2TXT.C
  2.  *------------------------------------------------------------------------
  3.  *
  4.  *  Program to convert a RBBS Messages file to text format
  5.  *
  6.  *   Tom Collins
  7.  *   09-15-90
  8.  */
  9.  
  10. #pragma pack(1)
  11.  
  12. typedef unsigned int Bit;
  13. typedef unsigned int uint;
  14.  
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18. #include <io.h>
  19. #include <stdarg.h>
  20. #include <fcntl.h>
  21. #include <sys\types.h>
  22. #include <sys\stat.h>
  23. #include <dos.h>
  24. #include "rbbs.h"
  25.  
  26. #define  TRUE     1
  27. #define  FALSE    0
  28.  
  29. #define  VERSION "v0.05"
  30.  
  31. #define  RBBS_EOL '\xE3'
  32. #define  DELETED_MESSAGE '\xE2'
  33.  
  34. char     *trim_string(char * );
  35. void     txt_printf(int ,char *,... );
  36. void     *read_rec(uint );
  37. void     twirl(void );
  38. char     *unpath(char * );
  39. void     center_txt_puts(char * );
  40.  
  41. int  fhin;
  42. FILE *fpout;
  43. int  lines_printed;
  44. int  use_page_feeds;
  45.  
  46. void main(int argc ,char *argv[] )
  47. {
  48.    uint   first_rec, next_avail_rec;
  49.    uint   current_rec;
  50.    uint   recs_in_msg;
  51.    uint   message_number, starting_message_number;
  52.    int    anything_exported;
  53.    int    no_privates;
  54.    int    i;
  55.    char   *filename, *p;
  56.    char   temp[80];
  57.    struct rbbs_checkpoint     *chkpt;
  58.    struct rbbs_message_header *hdr;
  59.    struct dosdate_t ddate;
  60.    struct dostime_t dtime;
  61.  
  62.    if (argc < 3 )
  63.       {
  64.       printf("Usage: MSG2TXT Messages_File_Name Text_File_Name [Start] [/NOPAGE] [/NOPRIVATE]\n\n" );
  65.       printf("       Messages_File_Name    = Name of your RBBS messages file\n" );
  66.       printf("       Text_File_Name        = Name of the file to write the text to\n" );
  67.       printf("       Start (Optional)      = Start exporting at what message number\n" );
  68.       printf("       /NOPAGE (Optional)    = Don't put page feeds in the output file\n" );
  69.       printf("       /NOPRIVATE (Optional) = Don't export private messages\n" );
  70.       exit(1 );
  71.       }
  72.    printf("MSG2TXT %s - Super Dooper RBBS Message to Text Converter, by Tom Collins\n\n" ,VERSION );
  73.  
  74.    printf("Converting: %s => %s... " ,strupr(argv[1] ) ,strupr(argv[2] ) );
  75.  
  76.    starting_message_number = 0;
  77.    use_page_feeds          = TRUE;
  78.    no_privates             = FALSE;
  79.    anything_exported       = FALSE;
  80.  
  81.    if (argc > 3 )
  82.       {
  83.       starting_message_number = atoi(argv[3] );
  84.       for (i = 3; i < argc; i++)
  85.      {
  86.          strupr(argv[i] );
  87.          if (strcmp(argv[i] ,"/NOPAGE" ) == 0 )
  88.         {
  89.         use_page_feeds = FALSE;
  90.         }
  91.          if (strcmp(argv[i] ,"/NOPRIVATE" ) == 0 )
  92.         {
  93.         no_privates = TRUE;
  94.         }
  95.      }
  96.       }
  97.  
  98.    fhin = open(argv[1] ,O_RDONLY|O_BINARY );
  99.    if (fhin < 0 )
  100.       {
  101.       printf("Error Opening Messages File %s - Program Aborted\n" ,argv[1] );
  102.       exit(1 );
  103.       }
  104.  
  105.    fpout = fopen(argv[2] ,"wt" );
  106.    if (fpout == NULL )
  107.       {
  108.       printf("Error Opening Text File %s - Program Aborted\n" ,argv[2] );
  109.       exit(1 );
  110.       }
  111.  
  112.    chkpt = read_rec(0 );
  113.  
  114.    first_rec      = atoi(chkpt->first_message );
  115.    next_avail_rec = atoi(chkpt->next_message );
  116.  
  117.    lines_printed = 0;
  118.    if (use_page_feeds )
  119.       {
  120.       txt_printf(0 ,"\f" );
  121.       }
  122.  
  123.    filename = unpath(argv[1] );
  124.    if ((p = strstr(filename ,"M.DEF" ) ) != NULL )
  125.       {
  126.       *p = '\0';
  127.       }
  128.    else if ((p = strchr(filename ,'.' ) ) != NULL )
  129.       {
  130.       *p = '\0';
  131.       }
  132.  
  133.    txt_printf(1 ,"" );
  134.    center_txt_puts("----------------------------------------" );
  135.  
  136.    sprintf(temp ,"%s Conference Messages" ,filename );
  137.    center_txt_puts(temp );
  138.  
  139.    _dos_getdate(&ddate );
  140.    _dos_gettime(&dtime );
  141.    sprintf(temp ,"Converted: %02u-%02u-%4u %02u:%02u:%02u" ,
  142.               ddate.month ,
  143.               ddate.day ,
  144.               ddate.year ,
  145.               dtime.hour ,
  146.               dtime.minute ,
  147.               dtime.second );
  148.  
  149.    center_txt_puts(temp );
  150.  
  151.    sprintf(temp ,"Created by MSG2TXT %s, by Tom Collins" ,VERSION );
  152.    center_txt_puts(temp );
  153.    center_txt_puts("----------------------------------------" );
  154.  
  155.    txt_printf(2 ,"" );
  156.  
  157.    current_rec = first_rec - 1;
  158.    while (current_rec < next_avail_rec )
  159.       {
  160.       hdr = read_rec(current_rec );
  161.       recs_in_msg = atoi(hdr->message_rec );
  162.       if (recs_in_msg <= 0 )
  163.          {
  164.          recs_in_msg = 1;
  165.          }
  166.       message_number = atoi(hdr->mess_number );
  167.  
  168.       if (message_number < starting_message_number  ||
  169.       (hdr->read_only == '*' && no_privates )   ||
  170.       hdr->active_indicator == DELETED_MESSAGE )
  171.          {
  172.      current_rec += recs_in_msg;
  173.          }
  174.       else
  175.          {
  176.      uint j, txt_size;
  177.          char *p, *one_line, *full_txt;
  178.  
  179.      txt_printf(1 ," Msg #: %4.4s" ,&(hdr->read_only ) );
  180.          txt_printf(1 ,"  From:  %31.31s Sent: %8.8s %5.5s" ,hdr->message_from ,hdr->message_date_sent ,hdr->message_time );
  181.          txt_printf(1 ,"    To:  %22.22s          Rcvd: -NO-" ,hdr->message_to );
  182.      txt_printf(2 ,"  Subj:  %25.25s" ,hdr->message_subject );
  183.  
  184.          current_rec++;
  185.      txt_size = (recs_in_msg - 1 ) << 7;
  186.  
  187.      full_txt = malloc(txt_size + 1 );
  188.          if (full_txt == NULL )
  189.             {
  190.             printf("\nMemory Allocation Error... Program Aborted.\n" );
  191.         exit(1 );
  192.             }
  193.  
  194.      for (j = 0; j < recs_in_msg-1; j++)
  195.             {
  196.         p = read_rec(current_rec++ );
  197.         memcpy(&full_txt[j << 7] ,p ,128 );
  198.             }
  199.      full_txt[txt_size] = '\0';
  200.  
  201.          one_line = full_txt;
  202.          for (j = 0; j < txt_size; j++ )
  203.             {
  204.             if (full_txt[j] == RBBS_EOL )
  205.                {
  206.                full_txt[j] = '\0';
  207.                trim_string(one_line );
  208.                if (one_line[0] != 0x01 && strncmp(one_line ,"SEEN-BY" ,7 ) != 0 )
  209.                   {
  210.                   txt_printf(1 ,"%s" ,one_line );
  211.                   }
  212.                one_line = &full_txt[j + 1];
  213.                }
  214.             }
  215.  
  216.          txt_printf(1 ,"" );
  217.          free(full_txt );
  218.  
  219.      anything_exported = TRUE;
  220.      }
  221.  
  222.       twirl();
  223.       }
  224.  
  225.    if (!anything_exported )
  226.       {
  227.       txt_printf(1 ,"No New Messages Found..." );
  228.       }
  229.  
  230.    printf("Done.\n");
  231.  
  232.    fclose(fpout );
  233.    close(fhin );
  234.  
  235.    exit(0);
  236. }
  237.  
  238. /*  TRIM_STRING
  239.  *----------------------------------------------------------------------------
  240.  *
  241.  *  Removes trailing spaces and '\n's
  242.  *  from a string.
  243.  *
  244.  *  Globals Used:
  245.  *     <none>
  246.  *
  247.  *  Returns:
  248.  *     The trimmed string
  249.  */
  250. char  *trim_string(char *s )
  251. {
  252.    int i;
  253.    for (i = strlen(s)-1; i >= 0; i--)
  254.       if (s[i] == ' ' || s[i] == '\n' || s[i] == '\r' )
  255.          s[i] = '\0';
  256.       else
  257.          break;
  258.  
  259.    return(s );
  260. }
  261.  
  262. /*  READ_REC
  263.  *----------------------------------------------------------------------------
  264.  *
  265.  *  Reads an RBBS record, and returns a pointer to it
  266.  *
  267.  */
  268. #define READ_BUFFER_SIZE (unsigned) 32512
  269.  
  270. void  *read_rec(uint rec_num )
  271. {
  272.    static char *buf = NULL;
  273.    static uint low_rec_in_ram = -1;
  274.    static uint high_rec_in_ram = -1;
  275.  
  276.    if (buf == NULL )
  277.       {
  278.       buf = malloc(READ_BUFFER_SIZE );
  279.       if (buf == NULL )
  280.          {
  281.          printf("\nMemory Allocation Error... Program Aborted.\n" );
  282.      exit(1 );
  283.          }
  284.       }
  285.  
  286.    /*
  287.     * See if we need to read from disk
  288.     */
  289.    if (rec_num < low_rec_in_ram || rec_num > high_rec_in_ram )
  290.       {
  291.       int stat;
  292.       long m;
  293.       long l, bytes_to_read;
  294.  
  295.       l = ((long ) rec_num) << 7L;           /* rec_num << 7 */
  296.       m = lseek(fhin ,l ,SEEK_SET );
  297.       bytes_to_read = filelength(fhin ) - l;
  298.       if (bytes_to_read > READ_BUFFER_SIZE )
  299.          {
  300.          bytes_to_read = READ_BUFFER_SIZE;
  301.          }
  302.       stat = read(fhin ,buf ,(unsigned) bytes_to_read );
  303.       low_rec_in_ram = rec_num;
  304.       high_rec_in_ram = rec_num + (uint) (bytes_to_read >> 7 ) - 1;
  305.       }
  306.  
  307.    return (buf + ((rec_num - low_rec_in_ram) << 7 ) );
  308. }
  309.  
  310. /*  TXT_PRINTF
  311.  *----------------------------------------------------------------------------
  312.  *
  313.  *  Prints a string to the text output file
  314.  *
  315.  */
  316. void txt_printf(int returns ,char *p ,... )
  317. {
  318.    int i;
  319.    va_list arg_ptr;
  320.    static char *buf = NULL;
  321.  
  322.    if (buf == NULL )
  323.       {
  324.       buf = malloc(8192 );
  325.       if (buf == NULL )
  326.          {
  327.          printf("\nMemory Allocation Error... Program Aborted.\n" );
  328.      exit(1 );
  329.          }
  330.       }
  331.    /*
  332.     *  Process input string and optional parameters
  333.     */
  334.    va_start(arg_ptr ,p );
  335.    i = vsprintf(buf ,p ,arg_ptr );
  336.  
  337.    fputs(buf ,fpout );
  338.    for (i = 0; i < returns; i++)
  339.       {
  340.       fputs("\n" ,fpout );
  341.       lines_printed++;
  342.       if (lines_printed == 60 && use_page_feeds )
  343.          {
  344.          fputs("\f\n\n\n" ,fpout );
  345.          lines_printed = 0;
  346.          }
  347.       }
  348. }
  349.  
  350. /*  TWIRL
  351.  *---------------------------------------------------------------------------
  352.  *
  353.  *  Prints a twirling clock on the screen
  354.  *
  355.  */
  356. void twirl(void )
  357. {
  358.    static int i = 0, j = 0;
  359.    static char *t = "/-\\|/-\\|";
  360.  
  361.    if ((j++ % 5 ) == 0 )
  362.       {
  363.       putchar(t[i++] );
  364.       putchar('\b' );
  365.  
  366.       if (t[i] == '\0' )
  367.      i = 0;
  368.       }
  369. }
  370.  
  371. /*  UNPATH
  372.  *----------------------------------------------------------------------------
  373.  *
  374.  *  Removes the path from a filename, and returns a pointer to it.
  375.  *
  376.  */
  377. char  *unpath(char *pathname )
  378. {
  379.    int  i;
  380.  
  381.    i = strlen(pathname );
  382.    if (i != 0 )
  383.       {
  384.       for ( ; i > 0; i-- )
  385.          {
  386.          if (pathname[i] == '\\' || pathname[i] == ':' )
  387.             {
  388.             i++;
  389.             break;
  390.             }
  391.          }
  392.       }
  393.    return(&pathname[i] );
  394. }
  395.  
  396. /*  CENTER_TXT_PUTS
  397.  *----------------------------------------------------------------------------
  398.  *
  399.  *  Writes a string to the text output file, centered on the line
  400.  *
  401.  */
  402. void center_txt_puts(char *s )
  403. {
  404.    int i;
  405.  
  406.    for (i = 0; i < (80 - strlen(s ) ) / 2; i++ )
  407.       {
  408.       txt_printf(0 ," " );
  409.       }
  410.    txt_printf(1 ,s );
  411. }
  412.